package org.robotjuice.turtleflip;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.PowerManager;
import android.os.Vibrator;
import android.widget.Toast;

import orientation.OrientationManager;
import orientation.OrientationListener;

/**
 * Main service
 * @author matias
 * under GPL v3 : http://www.gnu.org/licenses/gpl-3.0.html
 */
public class TurtleService extends Service implements OrientationListener
{
	PowerManager.WakeLock wakeLock;
	
	private Timer timer = new Timer();
	
	private static Context CONTEXT;
	
	/**
	 * Used in possible Toast needs.
	 * No idea why this is needed this, but it works.
	 */
	private Handler handler;
	
	private int ringerModeToRestore;
	
	private BroadcastReceiver screenReceiver; 
	
	@Override
	public IBinder onBind(Intent intent)
	{
		return null;
	}

	@Override
	public void onCreate()
	{
		super.onCreate();
		CONTEXT = this;
		
		/**
		 * Partial wake lock to prevent our service to go to sleep while screen is off
		 * This is horrible, get rid of this as soon as possible!
		 * Sorry, world.
		 * 
		 * It seems this is no longer needed since super Miika's super awesome idea works pretty well, see below.
		 * Let's keep the comments just in case.
		 * 
		 * TODO for matias: Nexus One doesn't like our code... ACTION_SCREEN_OFF triggers after you switch the screen again on.
		 */
		/*PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TurtleService");
        wakeLock.acquire();*/
		
		// Toast related, see above
		handler = new Handler(Looper.getMainLooper());
		
		// Check orientation every UPDATE_INTERVAL milliseconds
		//timer.scheduleAtFixedRate( new TimerTask() { public void run() { executeInterval(); } }, 0, UPDATE_INTERVAL);
		
		// Register broadcast receiver for ACTION_SCREEN_ON and ACTION_SCREEN_OFF
		//  to re-register accelerometer listener and prevent service sleeping while screen is off
		screenReceiver = new BroadcastReceiver() {
			@Override
			public void onReceive(Context context, Intent intent)
			{
				 // Check orientation after given time period
				timer.schedule(new TimerTask() { public void run() { OrientationManager.startListening(TurtleService.this); } }, 10000);
			}
		};
		registerReceiver(screenReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
		registerReceiver(screenReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
		
		// Let the world know our service is up
		Toast.makeText(this, "Turtle Flip service enabled.", Toast.LENGTH_SHORT).show();
	}
	
	@Override
	public void onStart(Intent intent, int startid)
	{
		//Toast.makeText(this, Integer.toString(startid), Toast.LENGTH_SHORT).show();
	}
	
	@Override
	public void onDestroy()
	{
		super.onDestroy();
		
		// Cancel the timer
		if (timer != null)
			timer.cancel();
		
		// Stop listening to sensor if necessary
		if (OrientationManager.isListening())
			OrientationManager.stopListening();
		
		// Release wake lock
		//wakeLock.release();
		
		Toast.makeText(this, "Turtle Flip service disabled.", Toast.LENGTH_SHORT).show();
	}
	
    public static Context getContext()
    {
        return CONTEXT;
    }
	
    /**
     * Catch sensor manager's trigger onFlipDown()
     */
	public void onFlipDown()
	{
		// Get current ringer mode and set new one
		AudioManager audioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
		ringerModeToRestore = audioManager.getRingerMode();
		audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
		
		// Let user know about the change
		Vibrator vb = ( Vibrator )getApplication().getSystemService( Service.VIBRATOR_SERVICE );
        vb.vibrate(100);
	}
	
	/**
	 * Catch sensor manager's trigger onFlipUp()
	 */
	public void onFlipUp()
	{
		// Restore ringer mode
		AudioManager audioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
		audioManager.setRingerMode(ringerModeToRestore);
		
		// Let user know about the change
		Vibrator vb = ( Vibrator )getApplication().getSystemService( Service.VIBRATOR_SERVICE );
        vb.vibrate(100);
	}
}
